package com.haohan.cloud.scm.wms.utils;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.haohan.cloud.scm.api.constant.enums.common.UseStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ProductPlaceStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ProductStatusEnum;
import com.haohan.cloud.scm.api.constant.enums.product.ProductionEmployeeTypeEnum;
import com.haohan.cloud.scm.api.constant.enums.product.StorageStatusEnum;
import com.haohan.cloud.scm.api.goods.dto.GoodsModelDTO;
import com.haohan.cloud.scm.api.goods.feign.GoodsModelFeignService;
import com.haohan.cloud.scm.api.manage.entity.UPassport;
import com.haohan.cloud.scm.api.manage.feign.UPassportFeignService;
import com.haohan.cloud.scm.api.product.dto.ProcessingResultDTO;
import com.haohan.cloud.scm.api.product.dto.ProcessingSourceDTO;
import com.haohan.cloud.scm.api.product.entity.ProductInfo;
import com.haohan.cloud.scm.api.product.entity.ProductionEmployee;
import com.haohan.cloud.scm.api.product.feign.ProductInfoFeignService;
import com.haohan.cloud.scm.api.product.feign.ProductionEmployeeFeignService;
import com.haohan.cloud.scm.api.product.req.ProductInfoReq;
import com.haohan.cloud.scm.api.product.req.ProductMatchSortingReq;
import com.haohan.cloud.scm.api.product.req.ProductionEmployeeReq;
import com.haohan.cloud.scm.api.product.req.QueryGoodsStorageReq;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseOrderDetail;
import com.haohan.cloud.scm.api.purchase.entity.PurchaseTask;
import com.haohan.cloud.scm.api.purchase.feign.PurchaseOrderDetailFeignService;
import com.haohan.cloud.scm.api.purchase.feign.PurchaseTaskFeignService;
import com.haohan.cloud.scm.api.purchase.req.PurchaseOrderDetailReq;
import com.haohan.cloud.scm.api.purchase.req.PurchaseTaskReq;
import com.haohan.cloud.scm.api.wms.entity.Cell;
import com.haohan.cloud.scm.api.wms.entity.Pallet;
import com.haohan.cloud.scm.common.tools.exception.EmptyDataException;
import com.haohan.cloud.scm.common.tools.exception.ErrorDataException;
import com.haohan.cloud.scm.common.tools.util.RUtil;
import com.haohan.cloud.scm.wms.service.CellService;
import com.haohan.cloud.scm.wms.service.EnterWarehouseService;
import com.haohan.cloud.scm.wms.service.PalletService;
import com.pig4cloud.pigx.common.core.constant.SecurityConstants;
import com.pig4cloud.pigx.common.core.util.R;
import lombok.AllArgsConstructor;
import org.springframework.stereotype.Component;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;

/**
 * @author xwx
 * @date 2019/6/13
 */
@Component
@AllArgsConstructor
public class ScmWmsUtils {

    private final GoodsModelFeignService goodsModelFeignService;
    private final PurchaseOrderDetailFeignService purchaseOrderDetailFeignService;
    private final ProductionEmployeeFeignService productionEmployeeFeignService;
    private final ProductInfoFeignService productInfoFeignService;
    private final PalletService palletService;
    private final CellService cellService;
    private final UPassportFeignService uPassportFeignService;
    private final PurchaseTaskFeignService purchaseTaskFeignService;
    private final EnterWarehouseService enterWarehouseService;
    /**
     * 商品规格信息
     * @param goodsModelId
     * @return
     */
    public GoodsModelDTO fetchGoodsModel(String goodsModelId) {
        R infoById = goodsModelFeignService.getInfoById(goodsModelId, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(infoById)) {
            throw new ErrorDataException("商品规格信息有误");
        }
        return BeanUtil.toBean(infoById.getData(), GoodsModelDTO.class);
    }

    /**
     * 查询商品库存
     * @param pmId
     * @param goodsModelId
     * @return
     */
    public ProductInfo queryGoodsStorage(String pmId,String goodsModelId) {
        QueryGoodsStorageReq req = new QueryGoodsStorageReq();
        req.setPmId(pmId);
        req.setGoodsModelId(goodsModelId);
        R r = productInfoFeignService.queryGoodsStorage(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || null == r.getData()) {
            throw new ErrorDataException("查询商品库存有误");
        }
        return BeanUtil.toBean(r.getData(), ProductInfo.class);
    }

    /**
     * 根据id 查询 uPassport
     * @param id
     * @return
     */
    public UPassport queryUPassportById(String id) {
        R<UPassport> byId = uPassportFeignService.getById(id, SecurityConstants.FROM_IN);
        if(!RUtil.isSuccess(byId) || byId.getData() == null){
            throw new EmptyDataException();
        }
        UPassport data = byId.getData();
        return data;
    }


    /**
     * 查询采购单明细
     * @param req
     * @return
     */
    public PurchaseOrderDetail fetchOrderDetail(PurchaseOrderDetailReq req) {
        R r = purchaseOrderDetailFeignService.getOneByPurchaseOrderDetailReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || r.getData()==null){
            throw new ErrorDataException("关联采购单明细出错");
        }
        return BeanUtil.toBean(r.getData(), PurchaseOrderDetail.class);
    }

    /**
     * 查询采购单明细列表
     * @param req
     * @return
     */
    public List<PurchaseOrderDetail> fetchOrderDetailList(PurchaseOrderDetailReq req) {
        R r = purchaseOrderDetailFeignService.getPurchaseOrderDetailList(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || r.getData()==null){
            throw new ErrorDataException("查询采购单明细列表出错");
        }
        List list = (List) r.getData();
        List<PurchaseOrderDetail> detailList = new ArrayList<>();
        for (Object o : list) {
            PurchaseOrderDetail orderDetail = BeanUtil.toBean(o, PurchaseOrderDetail.class);
            detailList.add(orderDetail);
        }
        return detailList;
    }

    /**
     * 修改采购单明细
     * @param detail
     * @return
     */
    public Boolean updateOrderDetail(PurchaseOrderDetail detail) {
        R r = purchaseOrderDetailFeignService.updateById(detail, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || !(Boolean)r.getData()){
            throw new ErrorDataException("修改采购单明细出错");
        }
        return true;
    }



    /**
     * 货品信息记录
     * @param req
     * @return
     */
    public ProductInfo fetchProductInfo(ProductInfoReq req) {
        R r = productInfoFeignService.getOneByProductInfoReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || r.getData()==null){
            throw new ErrorDataException("关联货品信息记录出错");
        }
        return BeanUtil.toBean(r.getData(), ProductInfo.class);
    }

    /**
     * 修改货品信息
     * @param productInfo
     * @return
     */
    public Boolean updateProductInfo(ProductInfo productInfo) {
        R r = productInfoFeignService.updateById(productInfo, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || !(Boolean)r.getData()){
            throw new ErrorDataException("修改失败");
        }
        return true;
    }

    /**
     * 货品拆分
     * @return
     */
    public ProcessingResultDTO fetchProductPeeling(ProcessingSourceDTO sourceDTO) {
        R r = productInfoFeignService.productPeeling(sourceDTO, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r)) {
            throw new ErrorDataException("货品拆分失败");
        }
        return BeanUtil.toBean(r.getData(), ProcessingResultDTO.class);
    }

    /**
     * 新增货品信息
     * @param productInfo
     * @return
     */
    public Boolean addProductInfo(ProductInfo productInfo){
        R r = productInfoFeignService.save(productInfo, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || !(Boolean)r.getData()){
            throw new ErrorDataException("新增货品信息失败");
        }
        return true;
    }


    /**
     * 查询托盘(货位)的状态
     * @param palletSn
     * @return
     */
    public Pallet fetchPalletStatus(String palletSn){
        Pallet pallet = new Pallet();
        pallet.setPalletSn(palletSn);
        pallet.setUseStatus(UseStatusEnum.enabled);
        pallet.setStorageStatus(StorageStatusEnum.idle);
        Pallet one = palletService.getOne(Wrappers.query(pallet));
        if (one==null){
            throw new ErrorDataException("没有查到托盘");
        }
        return one;
    }

    /**
     * 根据货品编号查询托盘信息
     * @param pmId
     * @param productSn
     * @return
     */
    public Pallet queryPallet(String pmId,String productSn){
        Pallet pallet = new Pallet();
        pallet.setPmId(pmId);
        pallet.setProductSn(productSn);
        Pallet one = palletService.getOne(Wrappers.query(pallet));
        return one;
    }

    /**
     * 查询货位状态
     * @param pmId
     * @param cellSn
     * @return
     */
    public Cell fetchCellStatus(String pmId, String cellSn){
        Cell cell = new Cell();
        cell.setPmId(pmId);
        cell.setCellSn(cellSn);
        cell.setUseStatus(UseStatusEnum.enabled);
        cell.setStorageStatus(StorageStatusEnum.idle);
        Cell cellOne = cellService.getOne(Wrappers.query(cell));
        if (cellOne==null){
            throw new ErrorDataException("没有查到货位");
        }
        return cellOne;
    }

    /**
     * 查询货位
     * @param cellSn
     * @return
     */
    public Cell queryCell(String cellSn){
        Cell cell = new Cell();
        cell.setCellSn(cellSn);
        Cell one = cellService.getOne(Wrappers.query(cell));
        return one;
    }


    /**
     * 查询生产部员工信息
     * @param pmId
     * @param uid
     * @return
     */
    public ProductionEmployee fetchByUid(String pmId, String uid) {
        // 生产部员工 (仓储管理员)
        ProductionEmployeeReq employeeReq = new ProductionEmployeeReq();
        employeeReq.setPmId(pmId);
        employeeReq.setPassportId(uid);
        employeeReq.setProductionEmployeeType(ProductionEmployeeTypeEnum.storage);
        employeeReq.setUseStatus(UseStatusEnum.enabled);
        R r = productionEmployeeFeignService.getOneByProductionEmployeeReq(employeeReq, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || r.getData()==null){
            throw new ErrorDataException("没有这个仓储管理员");
        }
        return BeanUtil.toBean(r.getData(),ProductionEmployee.class);
    }

    /**
     * 查询货品列表 按货品数量 降序
     * @param productInfo
     * @return
     */
    public List findProductInfoList(ProductInfoReq productInfo){
        R r = productInfoFeignService.getProductInfoList(productInfo, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || r.getData()==null){
            throw new ErrorDataException("查询货品列表失败");
        }
        return (List) r.getData();
    }

    /**
     * 查询采购任务
     * @param req
     * @return
     */
    public PurchaseTask fetchPurchaseTask(PurchaseTaskReq req){
        R r = purchaseTaskFeignService.getOneByPurchaseTaskReq(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || r.getData()==null){
            throw new ErrorDataException("查询采购任务失败");
        }
        return BeanUtil.toBean(r.getData(), PurchaseTask.class);
    }

    /**
     * 修改采购任务
     * @param task
     * @return
     */
    public Boolean updatePurchaseTask(PurchaseTask task){
        R r = purchaseTaskFeignService.updateById(task, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || !(Boolean)r.getData()){
            throw new ErrorDataException("修改采购任务失败");
        }
        return true;
    }

    /**
     * 根据新入库货品 匹配分拣
     * @param req pmId / realBuyNum / purchaseDetailSn
     * @return 返回修改后的货品信息
     */
    public ProductInfo enterProductMatchSorting(ProductMatchSortingReq req) {
        R r = productInfoFeignService.enterProductMatchSorting(req, SecurityConstants.FROM_IN);
        if (!RUtil.isSuccess(r) || null == r.getData()){
            throw new ErrorDataException("根据新入库货品 匹配分拣失败");
        }
        return BeanUtil.toBean(r.getData(), ProductInfo.class);
    }

    /**
     * 查询货品信息
     * @param productnum
     * @param goodsModelId
     * @return
     */
    public ProductInfo queryProductInfo(Integer productnum,String goodsModelId){
        ProductInfoReq req = new ProductInfoReq();
        req.setGoodsModelId(goodsModelId);
        req.setProductStatus(ProductStatusEnum.normal);
        req.setProductPlaceStatus(ProductPlaceStatusEnum.stock);
        R r = productInfoFeignService.getProductInfoList(req, SecurityConstants.FROM_IN);
        if(!RUtil.isSuccess(r) || r.getData()==null){
            throw new EmptyDataException();
        }
        BigDecimal sum = BigDecimal.ZERO;
        List list = (List)r.getData();
        for(Object obj : list){
            ProductInfo i = BeanUtil.toBean(obj, ProductInfo.class);
            if(i.getProductNumber().compareTo(BigDecimal.valueOf(productnum)) == 1){
                return i;
            }else{
                sum = sum.add(i.getProductNumber());
            }
            if(sum.compareTo(sum) == 1){
                return i;
            }
        }
        return null;
    }
}
